package system;

import java.io.IOException;

import java.io.InputStream;

import java.net.MalformedURLException;

import java.util.Hashtable;

import java.util.Properties;

import javax.management.Descriptor;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.modelmbean.ModelMBeanInfo;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import javax.naming.Context;

public class ManageWeblogic {

    private static String hostname = "";
    private static String portString = "";
    private static String username = "";
    private static String password = "";

    private static MBeanServerConnection connection = null;
    private static JMXConnector connector = null;
    //public static final ObjectName service;
    public static final String MBEAN_INTERFACE = "weblogic.management.security.authentication.UserEditorMBean";
    public static final String MBEAN_USERGROUP_INTERFACE = "weblogic.management.security.authentication.GroupEditorMBean";
    public static final String MBEAN_USERATTRIBUTE_INTERFACE = "weblogic.management.security.authentication.UserAttributeEditorMBean";

    public static MBeanServerConnection initConnection() throws IOException,
                                                                MalformedURLException {
        //Đọc thông số hệ thống
        ManageWeblogic obj = new ManageWeblogic();
        obj.readProperties();
        //Kết thúc
        String protocol = "t3";
        Integer portInteger = Integer.valueOf(portString);
        int port = portInteger.intValue();
        String jndiroot = "/jndi/";
        String mserver = "weblogic.management.mbeanservers.domainruntime";
        JMXServiceURL serviceURL =
            new JMXServiceURL(protocol, hostname, port, jndiroot + mserver);

        Hashtable h = new Hashtable();
        h.put(Context.SECURITY_PRINCIPAL, username);
        h.put(Context.SECURITY_CREDENTIALS, password);
        h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,
              "weblogic.management.remote");
        h.put("jmx.remote.x.request.waiting.timeout", new Long(10000));
        connector = JMXConnectorFactory.connect(serviceURL, h);
        connection = connector.getMBeanServerConnection();
        return connection;
    }
    
    private void readProperties() throws IOException {
        Properties props = new Properties();
        InputStream in = getClass().getResourceAsStream("SystemInfomation.properties");
        props.load(in);
        in.close();
        hostname = props.getProperty("hostname");
        portString = props.getProperty("portString");
        username = props.getProperty("username");
        password = props.getProperty("password");
    }

    public static ObjectName getAuthenticationProviderObjectName(String mBeanType) throws Exception {

        ObjectName userEditor = null;
        ObjectName mBeanTypeService =
            new ObjectName("com.bea:Name=MBeanTypeService,Type=weblogic.management.mbeanservers.MBeanTypeService");
        ObjectName rs =
            new ObjectName("com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean");
        ObjectName domainMBean =
            (ObjectName)connection.getAttribute(rs, "DomainConfiguration");
        ObjectName securityConfig =
            (ObjectName)connection.getAttribute(domainMBean,
                                                "SecurityConfiguration");
        ObjectName defaultRealm =
            (ObjectName)connection.getAttribute(securityConfig,
                                                "DefaultRealm");
        ObjectName[] authProviders =
            (ObjectName[])connection.getAttribute(defaultRealm,
                                                  "AuthenticationProviders");

        for (ObjectName providerName : authProviders) {
            //System.out.println("Auth provider is: " + providerName);
            if (userEditor == null) {
                ModelMBeanInfo info =
                    (ModelMBeanInfo)connection.getMBeanInfo(providerName);
                String className =
                    (String)info.getMBeanDescriptor().getFieldValue("interfaceClassName");
                //System.out.println("className is: " + className);

                if (className != null) {
                    String[] mba =
                        (String[])connection.invoke(mBeanTypeService,
                                                    "getSubtypes",
                                                    new Object[] { mBeanType },
                                                    new String[] { "java.lang.String" });
                    for (String mb : mba) {
                        //System.out.println("Model Bean is: " + mb);
                        if (className.equals(mb)) {
                            //System.out.println("Found a macth for the model bean and class name!");
                            userEditor = providerName;
                            return userEditor;
                        }
                    }
                }
            }
        }
        return null;
    }

    public static ObjectName getDefaultRealm() throws Exception {
        ObjectName service =
            new ObjectName("com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean");
        ObjectName domainMBean =
            (ObjectName)connection.getAttribute(service, "DomainConfiguration");
        ObjectName securityConfiguration =
            (ObjectName)connection.getAttribute(domainMBean,
                                                "SecurityConfiguration");
        ObjectName defaultRealm =
            (ObjectName)connection.getAttribute(securityConfiguration,
                                                "DefaultRealm");
        return defaultRealm;
    }

    public static void close() {
        try {
            connector.close();
        } catch (IOException ioe) {
            throw new RuntimeException(ioe);
        }
    }
}
